/*
 * ModeloMundo.java
 *
 * Created on 17 de mayo de 2008, 01:32 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package futbol.forrest.worldModel;

import futbol.tacticas.SituacionJugadores;
import futbol.General;
import futbol.forrest.utils.Types.*;
import futbol.forrest.gemetry.*;
import java.awt.Point;

/**
 *
 * @author Pablo
 */

public class WorldModel {
    
    private VecPosition[] teammates=new VecPosition[11];
    private VecPosition[] opponents=new VecPosition[11];
    private VecPosition ball;
    
    /** Creates a new instance of ModeloMundo */
    public WorldModel(){}

    public void setState(SituacionJugadores s){
        Point[] team = s.getMisJugadores();
        Point[] opps = s.getContrario();
        for(int i=0; i<s.getMisJugadores().length; i++){
            teammates[i] = new VecPosition(team[i].getX(), team[i].getY());
            opponents[i] = new VecPosition(opps[i].getX(), opps[i].getY());
        }
        ball = new VecPosition(s.getBola().getX(), s.getBola().getY());
    }
    

    public void getOpponentNearness(VecPosition pos, int nroPlayerDistNearness, double distNearness){
        getPlayerNearness(SetT.SET_OPPONENTS, 0, pos, nroPlayerDistNearness, distNearness);        
    }
    
    public void getTeammateNearness(int nroPlayer, VecPosition pos, int nroPlayerDistNearness, double distNearness){    
        getPlayerNearness(SetT.SET_TEAMMATES, nroPlayer, pos, nroPlayerDistNearness, distNearness);
    }
    
    private void getPlayerNearness(SetT set, int nroPlayer, VecPosition pos, int nroPlayerDistNearness, double distNearness){
        //OJO: en nroPlayer va de 1 a 11 y el arreglo va de 0 a 10
        nroPlayerDistNearness = 0;
        double dMinMag = 1000.0;
        
        VecPosition posPlayer;
        for(int i=0; i<11; i++){
            if(set == SetT.SET_OPPONENTS || (i+1) != nroPlayer){
                if(set == SetT.SET_TEAMMATES)
                    posPlayer = teammates[i];
                else
                    posPlayer = opponents[i];
                                                
                if(pos.getDistanceTo(posPlayer) < dMinMag ){
                    dMinMag = pos.getDistanceTo(posPlayer);
                    nroPlayerDistNearness = i+1;
                }                
            }            
        }
        distNearness = dMinMag;        
    }

    public int getCountOpponentInCone(double angCone, VecPosition start, VecPosition end){
        return getCountPlayersInCone(SetT.SET_OPPONENTS, 0, angCone, start, end);
    }
        
    //    This method returns the number of objects in the specified cone.
    //    A cone is like a piece of a pie, in which 'start' is
    //    the center of the pie, 'end' is the edge of the pie and 'dWidth' is the
    //    half width of the piece after distance 1. Only objects are taken into
    //    consideration that are within the set 'set' and have a confidence higher
    //    than the threshold defined in PlayerSettings.
    //    \param set ObjectSetT of which objects are taken into consideration
    //    \param dWidth half width of the cone after distance 1.0
    //    \param start center of the cone
    //    \param end position that is the end of the cone.
    //    \return number of objects part of 'set' and located in this cone.    
    private int getCountPlayersInCone(SetT set, int nroPlayer, double angCone, VecPosition start, VecPosition end){        
        //OJO: en nroPlayer va de 1 a 11 y el arreglo va de 0 a 10
        int iNr = 0;
        Line line = Line.makeLineFromTwoPoints(start, end);
        VecPosition posOnLine;
        VecPosition posPlayer;

        for(int i=0; i<11; i++){
            if(set == SetT.SET_OPPONENTS || (i+1) != nroPlayer){                
                if(set == SetT.SET_TEAMMATES)
                    posPlayer = teammates[i];
                else
                    posPlayer = opponents[i];
                
                posOnLine = line.getPointOnLineClosestTo(posPlayer);
                // whether posOnLine lies in cone is checked by three constraints
                // - does it lie in triangle (to infinity)
                // - lies between start and end (and thus not behind me)
                // - does it lie in circle
                if(posOnLine.getDistanceTo(posPlayer) < angCone*posOnLine.getDistanceTo(start)
                   && line.isInBetween( posOnLine, start, end )
                   && start.getDistanceTo( posPlayer ) < start.getDistanceTo( end ) ){
                    iNr++;
                }                
            }
        }    
        return iNr;            
    }    
    
    public VecPosition getPlayerPosition(SetT set, int nroPlayer){
        if(set == SetT.SET_TEAMMATES)
            return new VecPosition(teammates[nroPlayer-1]);
        else
            return new VecPosition(opponents[nroPlayer-1]);     
    }
    
    //TODO: Implementar!!!!
    /*! This method returns whether the position 'pos' is inside the playfield. */
    public boolean isInField( VecPosition pos, double dMargin ){
        return true;
        /*
        return Rect( 
                 VecPosition( + PITCH_LENGTH/2.0 - dMargin, 
                              - PITCH_WIDTH/2.0  + dMargin ),
                 VecPosition( - PITCH_LENGTH/2.0 + dMargin, 
                              + PITCH_WIDTH/2.0  - dMargin ) 
                 ).isInside( pos );
        */
    }

    //TODO: falta averiguar cual es el punto (centro) del arco contrario
    public static VecPosition getCenterPosGoalOpponents(){
        return new VecPosition(0,0);
    }

    //TODO: falta averiguar cuales son las pos de los palos
    public static void getPosGoalOpponents(VecPosition paloI, VecPosition paloD){
        paloI = new VecPosition(0,0);
        paloD = new VecPosition(0,0);
    }        
    
}
